package com.lubase.metadata.service.impl;

import com.alibaba.fastjson.JSON;
import com.lubase.metadata.mapper.MetaDatasourceMapper;
import com.lubase.metadata.model.ColumnMetaModel;
import com.lubase.metadata.model.ConstraintMetaModel;
import com.lubase.metadata.model.TableMetaModel;
import com.lubase.metadata.service.MetadataReadService;
import com.lubase.metadata.service.SpecificMetadataReadService;
import com.lubase.orm.exception.WarnCommonException;
import com.lubase.orm.model.auto.DmDatabaseEntity;
import com.lubase.orm.multiDataSource.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class MetadataReadServiceImpl implements MetadataReadService {

    @Autowired
    List<SpecificMetadataReadService> specificMetadataReadServices;
    @Autowired
    MetaDatasourceMapper metaDatasourceMapper;
    @Autowired
    ChangeDataSourceService changeDataSourceService;
    @Autowired
    DatabaseConnectBuilder databaseConnectBuilder;
    @Autowired
    DynamicDataSource dynamicDataSource;

    @Value("${custom.metadata-database-environment}")
    private String metadataDatabaseEnvironment;

    private SpecificMetadataReadService getSpecificMetadataReadServices(String databaseType) throws WarnCommonException {
        for (SpecificMetadataReadService specificMetadataReadService : specificMetadataReadServices) {
            if (specificMetadataReadService.databaseType().equals(databaseType)) {
                return specificMetadataReadService;
            }
        }
        throw new WarnCommonException("databaseType not found");
    }

    @SneakyThrows
    @Override
    public List<TableMetaModel> getTableList(String databaseId) {
        DmDatabaseEntity dmDatabaseEntity = getDatabaseEntity(databaseId);
        //切换到对应的数据库
        DBContextHolder.setDataSourceCode(databaseId);
        SpecificMetadataReadService specificMetadataReadService = getSpecificMetadataReadServices(dmDatabaseEntity.getDatabase_type());
        return specificMetadataReadService.getTableList(dmDatabaseEntity.getDatabase_name());
    }

    @SneakyThrows
    @Override
    public List<ColumnMetaModel> getTableColumnList(String databaseId) {
        DmDatabaseEntity dmDatabaseEntity = getDatabaseEntity(databaseId);
        //切换到对应的数据库
        SpecificMetadataReadService specificMetadataReadService = getSpecificMetadataReadServices(dmDatabaseEntity.getDatabase_type());

        DBContextHolder.setDataSourceCode(databaseId);
        List<ColumnMetaModel> list = specificMetadataReadService.getTableColumnListByDatabase(dmDatabaseEntity.getDatabase_name());
        for (ColumnMetaModel columnMetaModel : list) {
            // 如果columnName 等于id，不论大小写，且注释字段为空，则修改注释为“主键”
            if (columnMetaModel.getColumnName().equalsIgnoreCase("id") && StringUtils.isEmpty(columnMetaModel.getColumnComment())) {
                columnMetaModel.setColumnComment("主键");
            }
        }
        return list;
    }

    @SneakyThrows
    @Override
    public List<ConstraintMetaModel> getTableConstraintList(String databaseId) {
        DmDatabaseEntity dmDatabaseEntity = getDatabaseEntity(databaseId);
        //切换到对应的数据库
        SpecificMetadataReadService specificMetadataReadService = getSpecificMetadataReadServices(dmDatabaseEntity.getDatabase_type());

        DBContextHolder.setDataSourceCode(databaseId);
        List<ConstraintMetaModel> list = specificMetadataReadService.getTableConstraintList(dmDatabaseEntity.getDatabase_name());
        list.forEach(constraint -> {
            constraint.setIsFromDatabase(true);
        });
        return list;
    }

    @SneakyThrows
    private DmDatabaseEntity getDatabaseEntity(String databaseId) {
        if (StringUtils.isEmpty(databaseId)) {
            throw new WarnCommonException("databaseId is empty");
        }
        changeDataSourceService.changeDataSourceByTableCode("ms_database");
        List<DmDatabaseEntity> list = metaDatasourceMapper.getAllDatabaseSetting(databaseId, metadataDatabaseEnvironment);
        if (list.isEmpty()) {
            throw new WarnCommonException("databaseId not found");
        }
        DmDatabaseEntity dmDatabaseEntity = list.get(0);
        // 输出测试
        System.out.println(dmDatabaseEntity);
        DatabaseConnectModel database = databaseConnectBuilder.buildConnectModel(dmDatabaseEntity);
        Boolean result = null;
        result = dynamicDataSource.createDataSourceWithCheck(database);
        System.out.println(String.format("注册数据源：%s,注册结果：%s", database.getAliasCode(), result));
        if (!result) {
            log.info(JSON.toJSONString(dmDatabaseEntity));
            throw new WarnCommonException("数据源注册失败，请检查数据库连接信息");
        }
        DBContextHolder.setDataSourceCode(dmDatabaseEntity.getId().toString());
        return dmDatabaseEntity;
    }
}
